<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Mapbox Threebox Animation</title>
    <script src="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.js"></script>
    <link
      href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css"
      rel="stylesheet"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/controls/OrbitControls.js"></script>
    <script src="/node_modules/threebox-plugin/dist/threebox.min.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
      }
      #map {
        position: absolute;
        top: 0;
        bottom: 0;
        width: 100%;
      }
      #controls {
        position: absolute;
        top: 10px;
        left: 10px;
        background: white;
        padding: 10px;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <div id="controls">
      <button id="speed-up">加速</button>
      <button id="slow-down">减速</button>
    </div>
    <script>
      // Mapbox Access Token
      mapboxgl.accessToken =
        "pk.eyJ1IjoiemhvbmdkaXNodW1hIiwiYSI6ImNsdXVrbnNjeDA5c3EycnJ5eWN0endvamkifQ.13dZOqLYUshSE8HQVaHRcw";
      const map = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        center: [0, 0],
        zoom: 12,
      });

      map.on("load", function () {
        const tb = new Threebox(map, map.getCanvas().getContext("webgl"), {
          enableSelectingObjects: true,
          enableDraggingObjects: true,
        });

        // Define path
        const pathCoordinates = [
          [0, 0],
          [10, 10],
          [20, 0],
        ];

        // Create a Three.js geometry for the path
        const curve = new THREE.CatmullRomCurve3(
          pathCoordinates.map(
            (coord) => new THREE.Vector3(coord[0], 0, coord[1])
          )
        );

        const pathGeometry = new THREE.BufferGeometry().setFromPoints(
          curve.getPoints(100)
        );
        const pathMaterial = new THREE.LineBasicMaterial({ color: 0xff0000 });
        const pathLine = new THREE.Line(pathGeometry, pathMaterial);
        tb.add(pathLine);
        let options = {
          obj: "/public/car.glb",
          type: "gltf",
          scale: 0.1,
          units: "meters",
          rotation: { x: 90, y: 0, z: 0 },
          anchor: "center",
        };
        // Load model
        tb.loadObj(options, function (model) {
          model.scale.set(0.5, 0.5, 0.5); // Adjust model scale
          tb.add(model);

          // Animation variables
          let speed = 0.01;
          const duration = 10000; // Duration of the animation
          let startTime = Date.now();

          function animate() {
            requestAnimationFrame(animate);

            const elapsedTime = Date.now() - startTime;
            const t = (elapsedTime % duration) / duration; // [0, 1] value

            const point = curve.getPointAt(t);
            const tangent = curve.getTangentAt(t).normalize();
            const nextPoint = curve.getPointAt((t + speed) % 1);

            model.position.set(point.x, point.y, point.z);
            model.lookAt(nextPoint);

            tb.update();
          }

          animate();

          // Speed control
          document.getElementById("speed-up").addEventListener("click", () => {
            speed = Math.min(speed + 0.01, 0.1); // Increase speed, limit to 0.1
          });

          document.getElementById("slow-down").addEventListener("click", () => {
            speed = Math.max(speed - 0.01, 0.01); // Decrease speed, limit to 0.01
          });
        });
      });
    </script>
  </body>
</html>
